package cz.muni.fi.pb138.avradiation.Sensor;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * Class represents sensor entity, which has location and measured values.
 * 
 * @author Andrej Kuročenko <kurochenko@gmail.com>
 */
public class Sensor implements Comparable<Object> {
    /** Unique sensor identifier */
    private Long id = null;
    
    /** Sensor name */
    private String name = null;
    
    /** Unit which sensor measures */
    private String unit = null;
    
    /** Sensors location */
    private String location = null;
    
    /** Sensors description */
    private String description = null;
    
    /** Measured values by sensor in given time */
    private Map<Long, BigDecimal> measuredValues = new HashMap<Long, BigDecimal>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("Parameter [id] is null.");
        }
        this.id = id;
    }

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        if (unit == null) {
            throw new IllegalArgumentException("Parameter [unit] is null.");
        }
        this.unit = unit;
    }

    public String getLocation() {
        return location;
    }    

    public void setLocation(String location) {
        if (location == null) {
            throw new IllegalArgumentException("Parameter [location] is null.");
        }
        this.location = location;
    }
    
    public String getDescription() {
        return description;
    }    

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Parameter [name] is null");
        }
        this.name = name;
    }
    
    public void addMeasuredValue(Long millis, BigDecimal value) {
        if (millis == null) {
            throw new IllegalArgumentException("Parameter [millis] is null");
        }
        if (measuredValues.containsKey(millis)) {
            throw new IllegalArgumentException("Value with same date "
                    + "already exists");
        }
        
        measuredValues.put(millis, value);
    }

    public Map<Long, BigDecimal> getMeasuredValues(){
        return measuredValues;
    }

    @Override
    public String toString() {
        return "Sensor{" + "id=" + id + ", name=" + name + ", location=" 
                + location + ", description=" + description + 
                ", measuredValues=" + measuredValues + '}';
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Sensor other = (Sensor) obj;
        if ((this.name == null) 
                ? (other.name != null) : !this.name.equals(other.name)) {
            return false;
        }
        if ((this.location == null) 
                ? (other.location != null) 
                : !this.location.equals(other.location)) {
            return false;
        }        
        if (this.measuredValues != other.measuredValues 
                && (this.measuredValues == null 
                || !this.measuredValues.equals(other.measuredValues))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 19 * hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 19 * hash + (this.location != null 
                ? this.location.hashCode() : 0);
        hash = 19 * hash + (this.measuredValues != null 
                ? this.measuredValues.hashCode() : 0);
        return hash;
    }

    @Override
    public int compareTo(Object t) {
        Sensor s = (Sensor) t;
        int out = 0;
        if ((name != null) && (out = name.compareTo(s.getName())) != 0) {
            return out;
        }
        
        if ((location != null) && (out = location.compareTo(s.getLocation())) != 0) {
            return out;
        }
        
        if ((id != null) && (out = id.compareTo(s.getId())) != 0) {
            return out;
        }
        
        return out;
    }
}
